﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlaceHR.Processor.Processor;
using System.Configuration;

namespace PlaceHR.Processor
{
    class Program
    {
        /// <summary>
        /// 计算工资，假期，提醒，年龄，工龄等！
        /// </summary>
        /// <param name="args">arg1: EngineType, support: Salary/s, Vacation/v, Alert/a</param>
        /// <param name="args">arg2: ForceRecalculate, support: True, False</param>
        /// <param name="args">arg3: Year</param>
        /// <param name="args">arg4: Month</param>
        /// <param name="args">arg5: Day</param>
        static void Main(string[] args)
        {
            //if (args != null && args.Length > 0)
            //{
            //    foreach (var item in args)
            //    {
            //        Console.WriteLine(item);
            //    }
            //}

            //Test(args);
            Process(args);
        }

        private static void Test(string[] args)
        {
            IEngine engine = new SalaryEngine(2013, 9, 1);
            engine.ForceRecalculate = true;
            engine.Run();
        }

        private static void Process(string[] args)
        {
            if (args == null || args.Length < 1)
            {
                Console.WriteLine("args is null!");
                LogEvent("Engine Error", "args is null!");
                return;
            }

            string engineType = null;
            bool forceRecalculate = false;

            DateTime today = DateTime.Now;
            int year = 0;
            int month = 0;
            int day = today.Day;

            try
            {
                engineType = args[0].Trim().ToLower();
                if (args.Length > 1)
                {
                    forceRecalculate = Convert.ToBoolean(args[1]);
                }

                if (args.Length > 2)
                {
                    year = Convert.ToInt32(args[2]);
                }

                if (args.Length > 3)
                {
                    month = Convert.ToInt32(args[3]);
                }
                else
                {
                    GetTargetMonth(today, engineType, out year, out month);
                }

                if (args.Length > 4)
                {
                    day = Convert.ToInt32(args[4]);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("args is invalid!");
                LogEvent("Engine Error", ex.Message);
                return;
            }

            try
            {
                IEngine engine = null;
                switch (engineType)
                {
                    case "salary":
                    case "s":
                        engine = new SalaryEngine(year, month, day);
                        break;
                    case "vacation":
                    case "v":
                        engine = new VacationEngine(year, month);
                        break;
                    case "Alert":
                    case "a":
                        engine = new DailyEventEngine(year, month, day);
                        break;
                    default:
                        engine = new DailyEventEngine(year, month, day);
                        break;
                }

                engine.ForceRecalculate = forceRecalculate;
                engine.Year = year;
                engine.Month = month;
                engine.Day = day;

                engine.Run();
                Console.WriteLine("Done!");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                LogEvent("Engine Error", ex.Message);
            }
        }

        /// <summary>
        /// 用来计算目标月份，比如，今天可能计算的是本月的数据（Offset = 0），也可能是计算上月的数据（Offset = -1）
        /// </summary>
        /// <param name="today"></param>
        /// <param name="engineType"></param>
        /// <param name="year"></param>
        /// <param name="month"></param>
        private static void GetTargetMonth(DateTime today, string engineType, out int year, out int month)
        {
            year = today.Year;
            month = today.Month;

            string offsetConfigName = null;
            switch (engineType)
            {
                case "salary":
                case "s":
                    offsetConfigName = "SalaryMonthOffset";
                    break;
                case "vacation":
                case "v":
                    offsetConfigName = "VacationMonthOffset";
                    break;
                default:
                    break;
            }

            if (string.IsNullOrWhiteSpace(offsetConfigName))
            {
                return;
            }

            int offset = 0;
            if (ConfigurationManager.AppSettings[offsetConfigName] != null)
            {
                offset = Convert.ToInt32(ConfigurationManager.AppSettings[offsetConfigName]);
            }

            month = month + offset;
            if (month < 1)
            {
                month = month + 12;
                year--;
            }
            if (month > 12)
            {
                month = month - 12;
                year++;
            }
        }

        private static void LogEvent(string category, string message)
        {
            EventLog log = new EventLog
            {
                Category = category,
                Information = message,
                InsertDate = DateTime.Now
            };

            var dbContext = new HRDBEntities();
            dbContext.EventLog.AddObject(log);
            dbContext.SaveChanges();
        }

    }
}
